package com.yun.yun;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import java.util.HashMap;

public class UsbDeviceHelper {
	public static final int ERR_FIND_DEVICE      = -2;//找不到设备
	public static final int ERR_DEVICE_OPEN 	 = -4;//设备打开错误
	public static final int ERR_DEVICE_PERMISSON = -5;//设备无访问权限

	private static final String TAG = "UsbDeviceHelper";
	private static UsbManager mUsbManager = null;
	private static UsbDevice mUsbDevice = null;
	private static UsbDeviceConnection mDeviceConnection = null;

	private static PendingIntent mPermissionIntent;
	private final Context mContext;
	private static String usbDevicePath = "";
	private static final String ACTION_USB_DEVICE_PERMISSION = "com.android.usb.USB_PERMISSION";
	/*
	UsbManager	获得 USB 管理器，与连接的 USB 设备通信。
	UsbDevice	USB 设备的抽象，每个UsbDevice 都代表一个 USB 设备。
	UsbInterface	定义了设备的功能集，一个 UsbDevice 可能包含一个或多个UsbInterface，每个 Interface 都是独立的。
	UsbEndpoint	UsbEndpoint 是 interface 的通信通道。
	UsbDeviceConnection	host 与 device 建立的连接，并在 endpoint 传输数据。
	UsbRequest	USB 请求包。
	UsbConstants	USB 常量的定义
	 */
	// 注1：UsbManager.ACTION_USB_DEVICE_ATTACHED对应的广播在USB每次插入时都能监听到，所以用这个就可以监听USB插入。
	// 注2：UsbManager.ACTION_USB_DEVICE_DETACHED用来监听USB拔出广播。
	/**
	 * 注册USB设备插拔事件监听
	 */
	public UsbDeviceHelper(Context context) {
		mContext = context;
		
		//发一个延时广播
		mPermissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(
				"com.hdos.usbdevice.UsbDeviceLib.USB_PERMISSION"), 0);
		
		// 注册USB设备权限管理广播
		IntentFilter filter = new IntentFilter("com.hdos.usbdevice.UsbDeviceLib.USB_PERMISSION");
		
		filter.addAction(ACTION_USB_DEVICE_PERMISSION);
		filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
		filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
		mContext.registerReceiver(mUsbReceiver, filter);
	}

	public void RealseUsbDeviceHelper() {
		if (mContext != null)
			mContext.unregisterReceiver(mUsbReceiver);
	}

	// USB授权
	//USB 设备的插入
	private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
		public void onReceive(Context context, Intent intent) {
			if(intent == null)
				return;
			//设备插入，获取这个插入的UsbDevice
			UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
			String action = intent.getAction();
			if (TextUtils.isEmpty(action))
				return;
			if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
				// 设备插入，获取这个插入的UsbDevice
				// 向用户获取连接USB设备的授权
				Log.d(TAG, "UsbDevice (VID:" + usbDevice.getVendorId()
						+ ",PID:" + usbDevice.getProductId()
						+ ") DEVICE_ATTACHED");
				
				//requestUserPermission(usbDevice);
				
			} else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
				// 设备拔下，资源释放
				Log.d(TAG, "UsbDevice (VID:" + usbDevice.getVendorId()
						+ ",PID:" + usbDevice.getProductId()
						+ ") DEVICE_DETACHED");
				/*
				if (mUsbDevice !=null && mUsbDevice == usbDevice){
					mDeviceConnection.close();
				}
				*/
			} else if (action.equals(ACTION_USB_DEVICE_PERMISSION) ||
					action.equals("com.hdos.usbdevice.UsbDeviceLib.USB_PERMISSION")) {
				// 获取连接设备的权限
				boolean isGranted = intent.getBooleanExtra(
						UsbManager.EXTRA_PERMISSION_GRANTED, false);
				if (isGranted) {
					// 用户已授权
				} else {
					// 用户未授权
					
				}
				Log.d(TAG, "permission device " + isGranted);
			}else{

			}
		}
	};


    /**
     * 检测到设备插入之后，向用户请求连接设备的权限
     */
    private void requestUserPermission(UsbDevice usbDevice) {
    	//根据传入的NAME来取得对应的Object，然后转换成相应的服务对象
		//获取 UsbManager
    	mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
        if (mUsbManager.hasPermission(usbDevice)){
            //已经有权限的话，直接初始化驱动
           	//判断已经授予权限
            return;
        }
        //发一个延时广播(延迟执行的intent)
        PendingIntent mPendingIntent = PendingIntent.getBroadcast(mContext, 0,
                new Intent(ACTION_USB_DEVICE_PERMISSION), 0);
        //这一句会由系统弹出对话框，向用户获取连接授权
        mUsbManager.requestPermission(usbDevice, mPendingIntent);
    }
 
	public int getUsbFileDescriptor(int VendorId, int ProductID) {
		int UsbFileDescriptor = 0;
		mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
		//获取 USB 设备列表
		HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
		if (deviceList.size() <= 0) {
			Toast.makeText(mContext,"Device not found",Toast.LENGTH_SHORT).show();
			return ERR_FIND_DEVICE;
		}
		mUsbDevice = null;
		if (!deviceList.isEmpty()) {
			for (UsbDevice device : deviceList.values()) {
				usbDevicePath = device.getDeviceName();
				if ((device.getVendorId() == VendorId)
						&& (device.getProductId() == ProductID)) {
					mUsbDevice = device;
					// 判断下设备权限，如果没有权限，则请求权限
					if (!mUsbManager.hasPermission(mUsbDevice)) {
						mUsbManager.requestPermission(mUsbDevice,mPermissionIntent);
					}
					break;
				}
			}
		}
		if (mUsbDevice != null) {
			UsbDeviceConnection conn = null;
			if (mUsbManager.hasPermission(mUsbDevice)) {
				Log.d(TAG, "has permission");
				//打开设备
				conn = mUsbManager.openDevice(mUsbDevice);
			} else {
				Log.d(TAG, "no permission");
				Toast.makeText(mContext,"usb no permission",Toast.LENGTH_SHORT).show();
				return ERR_DEVICE_PERMISSON;
			}
			if (conn == null) {
				Toast.makeText(mContext,"usb open fail",Toast.LENGTH_SHORT).show();
				return ERR_DEVICE_OPEN;
			}
			//获取设备描述符
			UsbFileDescriptor = conn.getFileDescriptor();
			//input is not valid Modified UTF-8: illegal start byte 0xa7'
			//String strSN = conn.getSerial();

			Log.d(TAG, " getFileDescriptor: " + UsbFileDescriptor);
			//Log.d(TAG, " serial number: " + strSN);
			Toast.makeText(mContext,"DevicePath" + usbDevicePath,Toast.LENGTH_SHORT).show();

			mDeviceConnection = conn;

			return UsbFileDescriptor;
		}
		Toast.makeText(mContext,"Device not found",Toast.LENGTH_SHORT).show();
		return ERR_FIND_DEVICE;
	}

	public String getUsbDevPath() {
		return usbDevicePath;
	}

	public boolean isOpen() {
		if ((mUsbManager != null) && (mUsbDevice != null) && 
			(mDeviceConnection != null)&& (mUsbManager.hasPermission(mUsbDevice))) {
			return true;
		}
		return false;
	}
}
